/*
 * HtmlPainter.cpp
 *
 *  Created on: 30.7.2010
 *      Author: sber
 */

#include "HtmlPainter.h"
#include "themedatastorage.h"

#include <QTextLayout>
#include <QPainter>

HtmlPainter::HtmlPainter(Type type, ThemeData const & themeData)
  : themeData(themeData)
  , width(-1)
  , previousSize()
{
    switch(type) {
        case Content:
            font = *themeData.iListContentFont;
            break;
        case Info:
            font = *themeData.iListInfoFont;
            break;
    }
    
    layout.setFont(font);
}

HtmlPainter::~HtmlPainter()
{
}


void HtmlPainter::setContent(QString const & newContent)
{
    content = ConvertToDisplayForm(newContent);
    DoLayout(content);
}

QString HtmlPainter::ConvertToDisplayForm(QString const & string)
{
    QTextDocumentFragment document = QTextDocumentFragment::fromHtml(string);
    QString ret = document.toPlainText();
    ret.replace('\n', ' ');
    return ret;
}

QSize HtmlPainter::setOneLineMode(int width)
{
    return setLimitedMode(width, 1);
}

QSize HtmlPainter::setLimitedMode(int newWidth, int linesToShow)
{
    if(newWidth == width && linesToShow == linesToDraw) { return previousSize; }
    
    linesToDraw = linesToShow;
    width = newWidth;
    
    DoLayout(content);
     
    return previousSize;
}

void HtmlPainter::DoLayout(QString const & text)
{
    // ugh, not the first time text wrapping and ohter text functions don't quite work the same...
    int securityMargin = 20;
    
    if(width < securityMargin) { return; }
    
    QFontMetrics fm(font);
    int height = 0;
    int lineSpacing = fm.lineSpacing(); 
    
    layout.setText(text);
    layout.beginLayout();

    int lastLine = (linesToDraw > 0) ? (linesToDraw - 1) : INT_MAX;
    for(int i = 0; i < lastLine; ++i) {
        QTextLine line = layout.createLine();
        if(!line.isValid()) { break; }
        
        line.setLineWidth(width);
        height += lineSpacing;
    }
    
    QTextLine line = layout.createLine();
    if(line.isValid()) {
        line.setLineWidth(width);
        
        if(layout.createLine().isValid()) {
            // Have to elide
            int textStart = line.textStart();
            QString remainingText = text.mid(textStart);
            QString const elidedLastLine = fm.elidedText(remainingText, Qt::ElideRight, width - securityMargin);
            QString elidedWholeText = text.left(textStart);
            elidedWholeText += elidedLastLine;
            
            // Start new round with elided text
            layout.endLayout();
            DoLayout(elidedWholeText);
            return;
        }
    
        height += lineSpacing;
    }
    
    layout.endLayout();
    
    previousSize = QSize(width, height);
}

void HtmlPainter::SetFormatting(FormatRangeList const & formatting)
{
    layout.clearAdditionalFormats();
    layout.setAdditionalFormats(formatting);
}

QSize HtmlPainter::setUnlimitedMode(int width)
{
    return setLimitedMode(width, 0);
}

void HtmlPainter::paint(QPainter * painter, QRectF const & rect)
{
    painter->setFont(font);
    painter->setPen(Qt::black);
    
    QFontMetrics fm = painter->fontMetrics();
    int lineSpacing = fm.lineSpacing();
    QPointF paintPosition = rect.topLeft();
    
    for(int i = 0; i < layout.lineCount(); ++i) {
        QTextLine line = layout.lineAt(i);
        line.draw(painter, paintPosition);
        paintPosition.setY(paintPosition.y() + lineSpacing);
    }
}

